
;; test string:     var1 == var2
;; test tokenized:  id == id
(defvar *tokenString* `("id" "&&" "!" "(" "id" "==" "id" "||" "id" "<" "id" ")")) ;; string of tokens
;(setf *tokenString* `("id" "||" "id" "&&" "id" "&&" "id" "||" "(" "!" "id" "||" "id" "!=" "id" ")")) ;; string of tokens
(setf *tokenString* `("id" "&&" "(" "id" "||" "id" ")" ))
(defvar *token* (car *tokenString*)) ;; current token

;; Token functions

;; Sets *token* to the next token in the
;; token string for this parse
(defmethod nextToken ()
  (setf *tokenString* (cdr *tokenString*))
  (setf *token* (car *tokenString*)))
 

;; Tests the current token against another and
;; if they are equal then set *token* to the
;; next token
(defmethod matchNext (token)
  (if (string= token *token*)
      (progn (nextToken) (format t "found ~s~% stream: ~s~%~%" token *tokenString*) 1)
      (format t "~s does not match ~s~% steam: ~s~%~%" token *token* *tokenString*)))

;; just like matchNext, but throws and error
;; if there is no match
(defmethod requireNext (token)
  (format t "REQUIRE: ")
  (if (matchNext token)
      1
    (error "Unexpected token; not a sentence")))


;; start
(defmethod bool_expr ()
  (format t "_____________Starting bool_expr~%")
  (and_term)
  (if (matchNext "||")
      (and_term))
  1)


(defmethod and_term ()
  (format t "_____________Starting and_term~%")
  (bool_factor)
  (if (matchNext "&&")
      (bool_factor)))
  
(defmethod bool_factor ()
  (format t "_____________Starting bool_factor~%")
  (if (matchNext "(")
      (progn (bool_expr) (requireNext ")"))
      (if (matchNext "!") ;;elif
	  (bool_factor)
	  (if (or (matchNext "true") (matchNext "false")) ;;elif
	      ()
	      (relation_expr))))) ;;else

 
(defmethod relation_expr ()
  (format t "_____________Starting relation_expr~%")
  (requireNext "id")  
  (if (or (matchNext "==") (matchNext "!=") (matchNext "<") (matchNext ">") (matchNext "<=") (matchNext ">=")  )
      (requireNext "id")))



(defun parse ()
  (bool_expr)
  (if (= (list-length *tokenString*) 0)
      (format t "String is valid~%")
    (format t "Not a sentence~%")))

(parse)